"""
与token相关的类, 如 Token, Position, 常量
"""
import string

"""
常量
"""

DIGITS = '0123456789'
LETTERS = string.ascii_letters  # A~Z + a~z
LETTERS_DIGITS = LETTERS + DIGITS  # 字母加数字

TT_INT: str = 'INT'  # int
TT_FLOAT = 'FLOAT'  # float
TT_PLUS = 'PLUS'  # + 号
TT_MINUS = 'MINUS'  # - 减号
TT_MUL = 'MUL'  # * 乘号
TT_DIV = 'DIV'  # / 除号
TT_LPAREN = 'LPAREN'  # ( 左圆括号
TT_RPAREN = 'RPAREN'  # ) 右圆括号
TT_EOF = "EOF"  # 词法终止符
TT_EQ = 'EQ'  # = 等于号
TT_POW = 'POW'  # ^取幂
TT_IDENTIFIER = 'IDENTIFIER'  # 标识符
TT_KEYWORDS = 'KEYWORDS'
TT_EE = 'EE'  # ==
TT_NE = 'NE'  # !=
TT_LT = 'LT'  # <
TT_GT = 'GT'  # >
TT_LTE = 'LTE'  # <=
TT_GTE = 'GTE'  # >=
TT_COMMA = 'COMMA'  # ,
TT_ARROW = 'ARROW'  # ->
TT_STRING = 'STRING'  # 字符串
TT_LSQUARE = 'LSQUARE'  # 左中括号 [
TT_RSQUARE = 'RSQUARE'  # 右中括号 ]
TT_NEWLINE = "NEWLINE"  # ;\n 新的一行

KEYWORDS = [
    'var',  # 定义变量的关键字
    'and',  # 且逻辑运算符
    'or',  # 或逻辑运算符
    'not',  # 非逻辑运算符
    'if',
    'then',
    'elif',
    'else',
    'for',
    'to',
    'step',
    'while',
    'func',
    'end',
    'return',
    'continue',
    'break',
]

"""
Token类
"""


class Token:
    """
    分割的 token, 由类型和值组成
    """

    def __init__(self, type_, value=None, pos_start: 'Position' = None, pos_end: 'Position' = None):
        self.type = type_
        self.value = value

        if pos_start is not None:
            self.pos_start = pos_start.copy()
            self.pos_end = pos_start.copy()
            self.pos_end.advance(self.value)

        if pos_end is not None:
            self.pos_end = pos_end.copy()

    def matches(self, type_, value):
        """
        用于判断两个token是否相同
        """
        return type_ == self.type and value == self.value

    def matches_by_token(self, other: 'Token'):
        """
        用于判断两个token是否相同
        """
        return other.type == self.type and other.value == self.value

    def __repr__(self):
        if self.value is not None:
            return f'{self.type}:{self.value}'
        else:
            return f'{self.type}'


"""
Position位置类
"""


class Position:
    def __init__(self, idx, ln, col, fn, text):
        """
        :param idx: 索引下标
        :param ln: 行号(line)
        :param col: 列号(column)
        :param fn: 文件名(file name) ,报错用
        :param text: 内容文本
        :return:
        """
        self.idx = idx
        self.ln = ln
        self.col = col
        self.fn = fn
        self.text = text

    def advance(self, current_char):
        """
        预读取下一个字符, 配合 Lexer 类进行使用
        :param current_char:
        :return:
        """
        self.idx += 1
        self.col += 1

        if current_char == '\n':
            self.col = 0
            self.ln += 1

    def copy(self):
        """
        深拷贝
        :return: 一个深拷贝的 Position 对象
        """
        return Position(self.idx, self.ln, self.col, self.fn, self.text)
